package com.question_barrier.controller;

import com.question_barrier.entity.AnswerState;
import com.question_barrier.entity.Barrier;
import com.question_barrier.entity.BarrierState;
import com.question_barrier.entity.User;
import com.question_barrier.result.ResultModel;
import com.question_barrier.result.StateCode;
import com.question_barrier.service.AnswerStateService;
import com.question_barrier.service.BarrierService;
import com.question_barrier.service.BarrierStateService;
import com.question_barrier.service.UserService;
import com.question_barrier.utils.SnowflakeIdWorker;
import com.question_barrier.vo.barrier.BarrierResult;
import com.question_barrier.vo.barrier.LatestBarrierDegree;
import com.question_barrier.vo.user.UserBasic;
import com.question_barrier.vo.user.UserIntegral;
import com.question_barrier.vo.user.UserNamePhoto;
import com.question_barrier.vo.user.UserRankList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@RestController
@RequestMapping(value = "/user")
@Api(value = "用户模块", description = "用户模块接口信息")
/**
 * UserContorller
 * @author 何铭淇，陈晓明
 * @date 2019/7/17
 */
public class UserController {
    @Autowired
    UserService userService;
    @Autowired
    AnswerStateService answerStateService;
    @Autowired
    BarrierStateService barrierStateService;
    @Autowired
    BarrierService barrierService;
    SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
    //SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 查看user表中所有数据
     */
    /*@ApiOperation(value = "获取所有用户数据", notes = "获取user表中所有数据")
    @RequestMapping(value = "/allUser", method = RequestMethod.GET)*/
    public ResultModel<List<UserBasic>> getAllUser() {
        ResultModel resultModel = new ResultModel();
        List<User> userList = userService.getAllUser();
        resultModel.setCode(StateCode.REQUESTSUCCESS);  //请求成功
        resultModel.chooseMsg();

        List<UserBasic> userBasics = new ArrayList<UserBasic>();
        for (User user : userList) {
            userBasics.add(new UserBasic(user));
        }
        resultModel.setData(userBasics);
        return resultModel;
    }

    /**
     * 在user表中增加数据
     */
  /*  @ApiOperation(value = "添加新用户", notes = "添加用户数据到数据库")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "openId", value = "用户openId", required = true, paramType = "query")
    })
    @GetMapping(value = "/addUser")*/
    public ResultModel addUser(String openId) {
        ResultModel resultModel = new ResultModel();
        if (userService.existsByOpenId(openId)) {
            resultModel.setCode(StateCode.EXISTUSER);
            resultModel.chooseMsg();
        } else {
            long id = idWorker.nextId();
            long integral = 0;
            Date date = new Date();
            byte isDel = 0;
            User user = new User(id, openId, null, integral, date, id, date, id, isDel, null);
            resultModel.setCode(userService.addUser(user));
            resultModel.chooseMsg();
        }
        return resultModel;

    }

    @GetMapping(value = "/getUserScore")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "openId", value = "用户openId", required = true, paramType = "query")
    })
    @ApiOperation(value = "获取用户积分", notes = "如果用户open_id存在，返回积分，不存在该用户open_id,返回0积分")
    public ResultModel<UserIntegral> getUserScore(String openId) {
        ResultModel resultModel = new ResultModel();
        User user = userService.findByOpenId(openId);
        if (user == null) {
            resultModel.setCode(StateCode.NOTEXISTUSER);
            resultModel.chooseMsg();
        } else {
            resultModel.setCode(StateCode.FINDSUCCESS);
            resultModel.chooseMsg();
            UserIntegral userIntegral = new UserIntegral(user);
            resultModel.setData(userIntegral);
        }
        return resultModel;
    }

    /**
     * 用户登陆,输入用户openId，返回用户积分
     */
    @ApiOperation(value = "用户登陆", notes = "用户登陆时发送open_id到后台，返回用户数据（积分）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "openId", value = "用户openId", required = true, paramType = "query")
    })
    @GetMapping(value = "/loginUser")
    public ResultModel<UserIntegral> loginUser(String openId) {
        addUser(openId);
        return getUserScore(openId);
    }


    @RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)
    @ApiOperation(value = "更新用户名字和头像", notes = "如果openId不存在，则返回无此用户的提示")
    public ResultModel updateUserInfo(@RequestBody UserNamePhoto userNamePhoto) {
        ResultModel resultModel = new ResultModel();
        User user = userService.findByOpenId(userNamePhoto.getOpenId());
        if (user == null) {
            resultModel.setCode(StateCode.NOTEXISTUSER);
            resultModel.chooseMsg();
        } else {
            user.setName(userNamePhoto.getName());
            user.setPhotoUrl(userNamePhoto.getPhotoUrl());
            user.setUpdateAt(new Date());
            resultModel.setCode(userService.updateUser(user));
            resultModel.chooseMsg();
            UserBasic userBasic = new UserBasic(user);
            resultModel.setData(userBasic);
        }
        return resultModel;

    }
    @RequestMapping(value = "/pushResult", method = RequestMethod.POST)
    @ApiOperation(value = "推送用户答题结果")
    public ResultModel<LatestBarrierDegree> pushResult(@RequestBody BarrierResult barrierResult){
        ResultModel resultModel = new ResultModel();
        User user = userService.findByOpenId(barrierResult.getOpenId());
        if(user == null){
            resultModel.setCode(StateCode.NOTEXISTUSER);
            resultModel.chooseMsg();
        }else{
            /*更新积分
            遍历题目
                把第一次出现的题目插入表
                    对+2 错+0
                读取表里题目的答案，
                    如果由对到错-2，错到对+2
                把表里有的题目更新答案
            更新积分
             */
            updateScore(barrierResult);
            /*更新用户最新关卡
              判断当前关卡是最高，判断题目是全对
                if 最新关卡 < 关卡数
                    更新
                else
                    不更新

             */
            updateUserLatestBarrierId(barrierResult);
            BarrierState barrierState = barrierStateService.findByOpenIdAndGradeAndSubject(barrierResult.getOpenId(), barrierResult.getGrade(), barrierResult.getSubject());
            Barrier barrier = barrierService.findById(barrierState.getLatestBarrierId());
            LatestBarrierDegree latestBarrierDegree = new LatestBarrierDegree(barrier.getDegree());
            resultModel.setCode(StateCode.UPDATESUCCESS);
            resultModel.chooseMsg();
            resultModel.setData(latestBarrierDegree);
        }
        return resultModel;
    }

    public int updateUserLatestBarrierId(BarrierResult barrierResult){
        BarrierState barrierState = barrierStateService.findByOpenIdAndGradeAndSubject(barrierResult.getOpenId(), barrierResult.getGrade(), barrierResult.getSubject());
        if(barrierState != null){
            for(int i=0;i<barrierResult.getQuestionResultList().size();i++){
                if(0 == barrierResult.getQuestionResultList().get(i).getResult())
                    return StateCode.UPDATESUCCESS ;
            }
            Barrier barrier = barrierService.findById(barrierState.getLatestBarrierId());
            if(barrierResult.getPresentBarrierDegree() == barrier.getDegree()){
                List<Barrier> barrierList = barrierService.findByGradeAndSubject(barrierResult.getGrade(), barrierResult.getSubject());
                if(barrierResult.getPresentBarrierDegree() < barrierList.size()){
                    long newDegree = barrier.getDegree() + 1 ;
                    Barrier newBarrier = barrierService.findByGradeAndSubjectAndDegree(barrierResult.getGrade(), barrierResult.getSubject(), newDegree);
                    barrierState.setLatestBarrierId(newBarrier.getId());
                    barrierState.setUpdateAt(new Date());
                    barrierStateService.updBarrierState(barrierState);
                }
            }
            return StateCode.UPDATESUCCESS;
        }
        return StateCode.UPDATEFAIL;
    }

    public int updateScore(BarrierResult barrierResult){
        if(userService.existsByOpenId(barrierResult.getOpenId())) {
            long count = 0;
            for (int i = 0; i < barrierResult.getQuestionResultList().size(); i++) {
                if(answerStateService.existsByOpenIdAndQuestionId(barrierResult.getOpenId(), barrierResult.getQuestionResultList().get(i).getQuestionId())){
                    AnswerState answerState = answerStateService.findByOpenIdAndQuestionId(barrierResult.getOpenId(), barrierResult.getQuestionResultList().get(i).getQuestionId());
                    if(answerState.getState() !=  barrierResult.getQuestionResultList().get(i).getResult()){
                        if(barrierResult.getQuestionResultList().get(i).getResult() == 1)
                            count = count + 2;
                        else
                            count = count - 2;
                    }
                    answerState.setState(barrierResult.getQuestionResultList().get(i).getResult());
                    answerState.setUpdateAt(new Date());
                    answerStateService.updAnswerState(answerState);
                }else{
                    long id = idWorker.nextId();
                    Date date = new Date();
                    byte isDel = 0;
                    AnswerState answerState = new AnswerState(id, barrierResult.getOpenId(), barrierResult.getQuestionResultList().get(i).getQuestionId(), barrierResult.getQuestionResultList().get(i).getResult(), date, barrierResult.getOpenId(), date, barrierResult.getOpenId(), isDel);
                    answerStateService.insAnswerState(answerState);
                    if(barrierResult.getQuestionResultList().get(i).getResult() == 1){
                        count = count + 2;
                    }
                }
            }
            User user = userService.findByOpenId(barrierResult.getOpenId());
            user.setIntegral(user.getIntegral()+count);
            user.setUpdateAt(new Date());
            userService.updateUser(user);
            return StateCode.UPDATESUCCESS;
        }
        return StateCode.NOTEXISTUSER;
    }

    @RequestMapping(value = "/getRanking", method = RequestMethod.GET)
    @ApiOperation(value = "获取用户的排名和积分排名前10的用户信息")
    public ResultModel<UserRankList> getRanking(String openId) {
        ResultModel resultModel = new ResultModel();
        List<User> userList = userService.getAllUser();
        UserRankList userRankList = new UserRankList();
        User user = userService.findByOpenId(openId);
        if (user != null) {
            List<UserRankList.UserRankData> userMsg = new ArrayList<>();
            Collections.sort(userList);
            int num = userList.size() < 10 ? userList.size() : 10;
            for (int i = 0; i < num; i++) {
                userMsg.add(new UserRankList.UserRankData(userList.get(i)));
            }
            int rankNumber = 1;
            for (User u : userList) {
                if (u.getIntegral() > user.getIntegral()) {
                    rankNumber++;
                }
            }
            userRankList.setUserRank(rankNumber);
            userRankList.setUserRankDataList(userMsg);
            resultModel.setCode(StateCode.FINDSUCCESS);
            resultModel.chooseMsg();
            resultModel.setData(userRankList);
        } else {
            resultModel.setCode(StateCode.NOTEXISTUSER);
            resultModel.chooseMsg();
        }
        return resultModel;
    }

    /*@RequestMapping(value = "/updateUser",method = RequestMethod.GET)
    @ApiOperation(value = "更新用户数据")
    public ResultModel updateUser(long id, String open_id, String name,long integral,Date createAt,long createBy,
                                  Date updateAt,long updateBy,byte isDel,String photo_url)
    {
        User user = new User(id,open_id,name,integral,createAt,createBy,updateAt,updateBy,isDel,photo_url);
        int errorCode = userService.updateUser(user);
        ResultModel resultModel = new ResultModel();
        resultModel.setCode(errorCode);
        resultModel.setData(user);
        return ResultModelTool.handleResultModel(resultModel);
    }*/

    /*@RequestMapping(value = "/deleteUser/{id}",method = RequestMethod.GET)
    public ResultModel deleteUser(@PathVariable long id){
        int errorCode = userService.deleteUser(id);
        ResultModel resultModel = new ResultModel();
        resultModel.setCode(errorCode);
        List<User> userList = userService.getAllUser();
        Map<String,List<User>> UserMap = new HashMap<>();
        if (userList!=null){
            UserMap.put("users",userList);
        }
        resultModel.setData(UserMap);
        return ResultModelTool.handleResultModel(resultModel);
    }*/

    @Value("${wx.mp.appid}")
    private String appid;
    @Value("${wx.mp.secret}")
    private String secret;
    @Value("${wx.mp.loginUrl}")
    private String wxLoginUrl;
    @RequestMapping(value = "/openid", method = RequestMethod.GET)
    public String getOpenid(HttpServletResponse resp, HttpServletRequest req) {
        resp.setHeader("Access-Control-Allow-Origin", "*");
        resp.setContentType("text/json;charset=UTF-8");
        String code = req.getParameter("code");
        String param = "appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";
        String url = wxLoginUrl + "?" + param;
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject(url,String.class);
        return result;
    }

}
